package com.yqw.onlineDocs.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yqw.onlineDocs.common.ErrorCode;
import com.yqw.onlineDocs.constant.CommonConstant;
import com.yqw.onlineDocs.exception.ThrowUtils;
import com.yqw.onlineDocs.mapper.DocumentVersionMapper;
import com.yqw.onlineDocs.model.dto.documentVersion.DocumentVersionQueryRequest;
import com.yqw.onlineDocs.model.entity.DocumentVersion;
import com.yqw.onlineDocs.model.entity.User;
import com.yqw.onlineDocs.model.vo.DocumentVersionVO;
import com.yqw.onlineDocs.model.vo.UserVO;
import com.yqw.onlineDocs.service.DocumentVersionService;
import com.yqw.onlineDocs.service.UserService;
import com.yqw.onlineDocs.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 文档版本历史服务实现
 * 
 */
@Service
@Slf4j
public class DocumentVersionServiceImpl extends ServiceImpl<DocumentVersionMapper, DocumentVersion>
    implements DocumentVersionService {

  @Resource
  private UserService userService;

  /**
   * 校验数据
   *
   * @param documentVersion
   * @param add             对创建的数据进行校验
   */
  @Override
  public void validDocumentVersion(DocumentVersion documentVersion, boolean add) {
    ThrowUtils.throwIf(documentVersion == null, ErrorCode.PARAMS_ERROR);
    Long documentId = documentVersion.getDocumentId();
    Integer version = documentVersion.getVersion();
    String title = documentVersion.getTitle();
    String content = documentVersion.getContent();
    String remark = documentVersion.getRemark();
    // 创建数据时，参数不能为空
    if (add) {
      ThrowUtils.throwIf(documentId == null, ErrorCode.PARAMS_ERROR, "文档ID不能为空");
      ThrowUtils.throwIf(version == null, ErrorCode.PARAMS_ERROR, "版本号不能为空");
      ThrowUtils.throwIf(StringUtils.isBlank(content), ErrorCode.PARAMS_ERROR, "版本内容不能为空");
      // 标题可以为空，但如果提供了就要校验
      if (StringUtils.isNotBlank(title)) {
        ThrowUtils.throwIf(title.length() > 512, ErrorCode.PARAMS_ERROR, "标题长度不能超过512个字符");
      }
      // 备注可以为空，但如果提供了就要校验
      if (StringUtils.isNotBlank(remark)) {
        ThrowUtils.throwIf(remark.length() > 1024, ErrorCode.PARAMS_ERROR, "备注长度不能超过1024个字符");
      }
    }
    // 修改数据时，有参数则校验
    if (documentId != null) {
      ThrowUtils.throwIf(documentId <= 0, ErrorCode.PARAMS_ERROR, "文档ID不合法");
    }
    if (version != null) {
      ThrowUtils.throwIf(version <= 0, ErrorCode.PARAMS_ERROR, "版本号必须大于0");
    }
    if (StringUtils.isNotBlank(title)) {
      ThrowUtils.throwIf(title.length() > 512, ErrorCode.PARAMS_ERROR, "标题长度不能超过512个字符");
    }
    if (StringUtils.isNotBlank(content)) {
      ThrowUtils.throwIf(content.length() > 10000, ErrorCode.PARAMS_ERROR, "版本内容长度不能超过10000个字符");
    }
    if (StringUtils.isNotBlank(remark)) {
      ThrowUtils.throwIf(remark.length() > 1024, ErrorCode.PARAMS_ERROR, "备注长度不能超过1024个字符");
    }
  }

  /**
   * 获取查询条件
   *
   * @param documentVersionQueryRequest
   * @return
   */
  @Override
  public QueryWrapper<DocumentVersion> getQueryWrapper(DocumentVersionQueryRequest documentVersionQueryRequest) {
    QueryWrapper<DocumentVersion> queryWrapper = new QueryWrapper<>();
    if (documentVersionQueryRequest == null) {
      return queryWrapper;
    }
    // 从对象中取值
    Long id = documentVersionQueryRequest.getId();
    Long documentId = documentVersionQueryRequest.getDocumentId();
    Integer version = documentVersionQueryRequest.getVersion();
    String title = documentVersionQueryRequest.getTitle();
    String content = documentVersionQueryRequest.getContent();
    String remark = documentVersionQueryRequest.getRemark();
    Long userId = documentVersionQueryRequest.getUserId();
    String sortField = documentVersionQueryRequest.getSortField();
    String sortOrder = documentVersionQueryRequest.getSortOrder();
    // 补充需要的查询条件
    // 模糊查询
    queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
    queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
    queryWrapper.like(StringUtils.isNotBlank(remark), "remark", remark);
    // 精确查询
    queryWrapper.eq(ObjectUtils.isNotEmpty(documentId), "documentId", documentId);
    queryWrapper.eq(ObjectUtils.isNotEmpty(version), "version", version);
    queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
    queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
    // 排序规则
    queryWrapper.orderBy(SqlUtils.validSortField(sortField),
        sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
        sortField);
    return queryWrapper;
  }

  /**
   * 获取文档版本历史封装
   *
   * @param documentVersion
   * @param request
   * @return
   */
  @Override
  public DocumentVersionVO getDocumentVersionVO(DocumentVersion documentVersion, HttpServletRequest request) {
    // 对象转封装类
    DocumentVersionVO documentVersionVO = DocumentVersionVO.objToVo(documentVersion);

    // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
    // region 可选
    // 1. 关联查询用户信息
    Long userId = documentVersion.getUserId();
    User user = null;
    if (userId != null && userId > 0) {
      user = userService.getById(userId);
    }
    UserVO userVO = userService.getUserVO(user);
    documentVersionVO.setUser(userVO);
    // endregion

    return documentVersionVO;
  }

  /**
   * 分页获取文档版本历史封装
   *
   * @param documentVersionPage
   * @param request
   * @return
   */
  @Override
  public Page<DocumentVersionVO> getDocumentVersionVOPage(Page<DocumentVersion> documentVersionPage,
      HttpServletRequest request) {
    List<DocumentVersion> documentVersionList = documentVersionPage.getRecords();
    Page<DocumentVersionVO> documentVersionVOPage = new Page<>(documentVersionPage.getCurrent(),
        documentVersionPage.getSize(), documentVersionPage.getTotal());
    if (CollUtil.isEmpty(documentVersionList)) {
      return documentVersionVOPage;
    }
    // 对象列表 => 封装对象列表
    List<DocumentVersionVO> documentVersionVOList = documentVersionList.stream().map(documentVersion -> {
      return DocumentVersionVO.objToVo(documentVersion);
    }).collect(Collectors.toList());

    // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
    // region 可选
    // 1. 关联查询用户信息
    Set<Long> userIdSet = documentVersionList.stream().map(DocumentVersion::getUserId).collect(Collectors.toSet());
    Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
        .collect(Collectors.groupingBy(User::getId));
    // endregion

    documentVersionVOPage.setRecords(documentVersionVOList);
    return documentVersionVOPage;
  }

}
